import { Table, Input, Form, Card, message, Select, Switch } from 'antd';
import React, { Component } from 'react';
import { PageHeaderWrapper } from '@ant-design/pro-layout';
import { connect } from 'dva';
import { axconst } from '@/shared/axconst';
import { axhelper } from '@/shared/axhelper';
import './index.css';
import AxOperationButton from '@/components/AxList/AxOperationButton/index';
import AxColumnAction from '@/components/AxList/AxColumnAction/index';
import AxColumnEnum from '@/components/AxList/AxColumnEnum/index';
import { AxValidator } from '@/components/AxForm/AxFormItem/AxValidator';
import { AxResizable } from '@/components/AxBase/AxResizable';
import { AxInputForSimple } from '@/components/AxBase/AxInput';
import { AxTable } from '..';

const { Option } = Select;
const EditableContext = React.createContext();

class AxTree extends Component {
  constructor(props) {
    super(props);
    this.state = {
      addingKey: null,
      editingKey: null,
      expandedRowKeys: [],
      /** 配置操作按钮 */
      axButtons: [
        {
          text: '刷新',
          icon: 'redo',
          type: 'primary',
          permissions: props.needPermissions === false ? 0 : 1,
          onClick: () => this.handleRead(),
        },
        {
          text: '添加',
          icon: 'plus',
          type: 'primary',
          permissions: props.needPermissions === false ? 0 : 2,
          onClick: () => this.create(null, {}),
        },
      ],
      columns: props.columns || [],
      currentRecord: null,
      selectedKey: null,
    };
  }

  /** 添加时的标识id */
  cid = '9xxxxxxxxxxx9';

  /** 不能修改的列 */
  columnsNoChange = ['id'];

  /** 简单查询项 */
  searchOption = [];

  /** 控制操作按钮的状态 */
  axHandleButtonsVisible = () => {
    if (this.state.axButtons) {
      this.setState(state => {
        const btn = state.axButtons.slice();
        btn[1].disabled = !!(state.editingKey || state.addingKey);
        return { axButtons: btn };
      });
    }
  };

  /** 会在组件挂载后（插入 DOM 树中）立即调用  --生命周期函数 */
  componentDidMount() {
    this.handleRead();
  }

  /** 初始化数据 */
  handleRead = () => {
    const { handleRead } = this.props;
    if (handleRead) {
      handleRead(this.axParams, null);
    }
    this.setState({
      addingKey: null,
      editingKey: null,
    });
    this.axHandleButtonsVisible();
  };

  /** 标记添加行 */
  isAdding = record => record.cid === this.state.addingKey;

  /** 标记修改行 */
  isEditing = record => record.id === this.state.editingKey;

  /** 取消 */
  cancel = (e) => {
    if (e) e.stopPropagation();

    const { data } = this.props;
    const newData = this.delData(data);
    this.setState({
      editingKey: null,
      addingKey: null,
      data: newData,
      currentRecord: null,
    });
    this.axHandleButtonsVisible();
  };

  /** 取消时，删除行 */
  delData = data => {
    if (data.find) {
      const f = data.find(i => i.cid === this.cid);
      if (data.indexOf(f) >= 0) {
        data.splice(data.indexOf(f), 1);
        if (data.length === 0) data = null;
        return data;
      }

      data.forEach(i => {
        if (i.children && i.children.length > 0) {
          i.children = this.delData(i.children);
        }
      });
    }
    return data;
  };

  /** 添加 */
  create = (e, record) => {
    if (e) e.stopPropagation();

    const { data, createObj = {} } = this.props;
    const obj = {
      cid: this.cid,
      parentId: record.id,
      ...createObj,
    };
    this.addData(record.id, data, obj);
    this.setState(({ expandedRowKeys }) => {
      expandedRowKeys.push(record.id);
      return {
        addingKey: this.cid,
        currentRecord: obj,
        expandedRowKeys,
        data,
      };
    });
    this.axHandleButtonsVisible();
  };

  /** 添加时，新增行 */
  addData = (id, data, obj) => {
    if (!id) {
      data.push(obj);
    } else {
      data.some(i => {
        if (id === i.id) {
          if (!i.children) {
            i.children = [];
          }
          i.children.push(obj);
          return true;
        }
        if (i.children && i.children.length > 0) {
          this.addData(id, i.children, obj);
        }
      });
    }
  };

  /** 修改 */
  update = (e, record) => {
    if (e) e.stopPropagation();
    this.setState({
      editingKey: record.id,
      currentRecord: record,
    });

    this.axHandleButtonsVisible();
  };

  /** 保存 */
  save = (e, form) => {
    if (e) e.stopPropagation();

    form.validateFields((error, row) => {
      if (error) {
        return;
      }
      const { handleCreate, handleUpdate } = this.props;
      const { currentRecord } = this.state;
      /** 添加 */
      if (handleCreate && currentRecord.cid && currentRecord.cid === this.cid) {
        handleCreate(null, {
          ...row,
          parentId: currentRecord.parentId,
        }).then(res => {
          message.success('添加成功');
          this.handleRead();
          this.setState({
            editingKey: null,
            addingKey: null,
            currentRecord: null,
          });
          this.axHandleButtonsVisible();
        });
      } else if (handleUpdate) {
        /** 修改 */
        const params = { menuId: currentRecord.id };
        handleUpdate(params, {
          id: currentRecord.id,
          ...row,
          parentId: currentRecord.parentId,
        }).then(res => {
          message.success('修改成功');
          this.handleRead();
          this.setState({
            editingKey: null,
            addingKey: null,
            currentRecord: null,
          });
          this.axHandleButtonsVisible();
        });
      }
    });
  };

  /** 删除 */
  destroy = (e, id) => {
    if (e) e.stopPropagation();

    const { handleDestroy } = this.props;
    const params = { id: id };
    if (handleDestroy) {
      handleDestroy(params, null).then(res => {
        message.success('删除成功');
        this.handleRead();
      });
    }
  };

  /** 启用 */
  enabled = (e, id) => {
    if (e) e.stopPropagation();

    const { handleEnabled } = this.props;
    const params = { id: id };
    if (handleEnabled) {
      handleEnabled(params, null).then(res => {
        message.success('启用成功');
        this.handleRead();
      });
    }
  };

  /** 禁用 */
  disabled = (e, id) => {
    if (e) e.stopPropagation();

    const { handleDisabled } = this.props;
    const params = { id: id };
    if (handleDisabled) {
      handleDisabled(params, null).then(res => {
        message.success('禁用成功');
        this.handleRead();
      });
    }
  };

  /** 展开节点 */
  handleExpandedRowsChange = expandedRows => {
    this.setState({
      expandedRowKeys: expandedRows,
    });
  };

  /** 查询 */
  handleSearch = (e, fieldsValue) => {
    /** 阻止默认事件 */
    if (e) e.preventDefault();
    this.axParams = fieldsValue;
    this.handleRead();
  };

  /** 双击修改 */
  handleDoubleClick = (record, e) => {
    e && e.stopPropagation();
    this.update(null, record);
  };

  /** 单击 */
  handleClick = ({ record, event: e }) => {
    const { selectedKey } = this.state;
    e && e.stopPropagation();
    if (selectedKey == record.id) return;

    const { handleClick: handleClickFromProps } = this.props;
    handleClickFromProps && handleClickFromProps(record);
    this.setState({
      selectedKey: record.id,
    });
  };

  /** 改变宽度 */
  handleResize = index => (e, { size }) => {
    this.setState(({ columns }) => {
      const nextColumns = [...columns];
      nextColumns[index] = {
        ...nextColumns[index],
        width: size.width,
      };
      return { columns: nextColumns };
    });
  };

  render() {
    const {
      form,
      data,
      loading,
      canCreate = true,
      canUpdate = true,
      canDestroy = false,
      canEnable = false,
      canDisable = false,
      cardBodyStyle,
      showPageHeaderWrapper = true,
    } = this.props;
    const { operateValues, expandedRowKeys, columns = [] } = this.state;

    /** 覆盖默认的 table 元素 */
    const components = {
      header: {
        cell: AxResizable,
      },
      body: {
        cell: EditableCell,
      },
    };

    let axcolumns = columns.map(col => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        /** 设置单元格属性 */
        onCell: record => ({
          record,
          required: col.required,
          enumName: col.enumName,
          dataIndex: col.dataIndex,
          booleantype: col.booleantype && col.booleantype.toString(),
          title: col.title,
          columnsNoChange: this.columnsNoChange,
          adding: this.isAdding(record),
          editing: this.isEditing(record),
        }),
      };
    });

    axcolumns.push({
      title: '操作',
      width: axconst.width.operate8,
      render: (text, record) => {
        const { editingKey, addingKey } = this.state;
        const { needPermissions } = this.props;
        const editable = this.isEditing(record);
        const addable = this.isAdding(record);
        const disabled = addingKey !== null || editingKey !== null;

        return editable || addable ? (
          <span>
            <EditableContext.Consumer>
              {form => (
                <a onClick={(e) => this.save(e, form)} style={{ marginRight: 8 }}>
                  保存
                </a>
              )}
            </EditableContext.Consumer>
            <a onClick={(e) => this.cancel(e)}>取消</a>
          </span>
        ) : (
            <AxColumnAction
              buttons={[
                {
                  text: '添加',
                  permissions: needPermissions === false ? 0 : 2,
                  // icon: 'plus',
                  disabled,
                  show: canCreate,
                  onClick: (e) => this.create(e, record),
                },
                {
                  text: '修改',
                  permissions: needPermissions === false ? 0 : 4,
                  // icon: 'edit',
                  disabled,
                  show: canUpdate,
                  onClick: (e) => this.update(e, record),
                },
                {
                  text: '删除',
                  permissions: needPermissions === false ? 0 : 8,
                  // icon: 'delete',
                  disabled,
                  show: canDestroy,
                  popconfirm: true,
                  onClick: (e) => this.destroy(e, record.id),
                },
                {
                  text: '启用',
                  permissions: needPermissions === false ? 0 : 16,
                  // icon: 'check-circle',
                  disabled: disabled || record.state === 1,
                  show: canEnable,
                  popconfirm: true,
                  onClick: (e) => this.enabled(e, record.id),
                },
                {
                  text: '禁用',
                  permissions: needPermissions === false ? 0 : 32,
                  // icon: 'stop',
                  disabled: disabled || record.state === 2,
                  show: canDisable,
                  popconfirm: true,
                  onClick: (e) => this.disabled(e, record.id),
                },
              ]}
            />
          );
      },
    });

    /** 伸缩列 */
    if (axcolumns) {
      const len = axcolumns.length - 1;
      axcolumns = axcolumns.map((col, idx) => ({
        ...col,
        /** 设置头部单元格属性 */
        onHeaderCell: column => ({
          width: column.width,
          last: len === idx,
          onResize: this.handleResize(idx),
        }),
      }));
    }

    /** 操作按钮属性配置（包含简单查询） */
    const operationProps = {
      advanceSearch: false,
      buttons: this.state.axButtons,
      searchOption: this.searchOption,
      handleSearch: this.handleSearch,
    };

    const card =
      <Card bordered={false} bodyStyle={cardBodyStyle}>
        <AxOperationButton {...operationProps} />
        <EditableContext.Provider value={form}>
          <AxTable
            rowKey="id"
            size='small'
            bordered
            pagination={false}
            components={components}
            loading={loading}
            data={{ list: data }}
            expandedRowKeys={expandedRowKeys}
            columns={axcolumns}
            addemptycolumn={true}
            checkboxType='radio'
            scroll={{ x: 'max-content' }}
            onExpandedRowsChange={this.handleExpandedRowsChange}
            onDoubleClick={this.handleDoubleClick}
            onClick={this.handleClick}
          />
        </EditableContext.Provider>
      </Card>;

    return (
      showPageHeaderWrapper === true ?
        <PageHeaderWrapper title={false}>
          {card}
        </PageHeaderWrapper>
        : card
    );
  }
}

class EditableCell extends Component {
  /** 获取编辑输入框 */
  getInput = () => {
    const { title, enumName, booleantype } = this.props;
    if (enumName) {
      const options = axhelper.getDicByEnumName(enumName);
      return (
        <Select style={{ width: '100%' }} placeholder={`请选择${title}`}>
          {options.map((d, idx) => (
            <Option key={idx} value={d.value}>
              {d.text}
            </Option>
          ))}
        </Select>
      );
    }
    if (booleantype) {
      return (
        <Switch value={booleantype === "true" ? true : false} />
      );
    }
    return <Input />;
  };

  renderCell = ({ getFieldDecorator }) => {
    const {
      adding,
      editing,
      dataIndex,
      title,
      record,
      children,
      required,
      enumName,
      booleantype,
      columnsNoChange,
      ...restProps
    } = this.props;
    let canChange = true;
    if (columnsNoChange && columnsNoChange.find) {
      canChange = !columnsNoChange.find(i => i == dataIndex);
    }
    return (
      <td {...restProps}>
        {adding ? (
          <Form.Item style={{ margin: 0 }}>
            {getFieldDecorator(dataIndex, {
              valuePropName: booleantype ? 'checked' : 'value',
              rules: [
                {
                  label: title,
                  required,
                  validator: AxValidator,
                },
              ],
              initialValue: record[dataIndex],
            })(this.getInput())}
          </Form.Item>
        ) : editing && canChange ? (
          <Form.Item style={{ margin: 0 }}>
            {getFieldDecorator(dataIndex, {
              valuePropName: booleantype ? 'checked' : 'value',
              rules: [
                {
                  label: title,
                  required,
                  validator: AxValidator,
                },
              ],
              initialValue: record[dataIndex], // ? record[dataIndex].toString() : null,
            })(this.getInput())}
          </Form.Item>
        ) : (
              children
            )}
      </td>
    );
  };

  render() {
    return <EditableContext.Consumer>{this.renderCell}</EditableContext.Consumer>;
  }
}

export default Form.create()(AxTree);
